﻿using System;
using System.Drawing;
using System.IO;
using System.Windows.Forms;
using CalcSharp.Properties;
using WeifenLuo.WinFormsUI.Docking;
using System.Diagnostics;
using CalcSharp.Ui;

namespace CalcSharp.MDIUI.ToolBars
{
    public partial class FileExplorer : DockContent
    {
        public FileExplorer()
        {
            InitializeComponent();
            CreateDriveList();
        }

        private void InsertDriveToList(DriveInfo di)
        {
            GroupBox DriveBox = new GroupBox();
            Label DriveInfo = new Label();
            ProgressBar DriveUsage = new ProgressBar();
            PictureBox DriveIcon = new PictureBox();
 
            DriveBox.Controls.Add(DriveInfo);
            DriveBox.Controls.Add(DriveUsage);
            DriveBox.Controls.Add(DriveIcon);
            DriveBox.Dock = System.Windows.Forms.DockStyle.Top;
            DriveBox.Location = new System.Drawing.Point(0, 0);
            DriveBox.Name = di.Name;
            DriveBox.Size = new System.Drawing.Size(284, 59);
            DriveBox.TabStop = false;
            DriveBox.Text = di.Name + " - " + di.VolumeLabel;
            DriveBox.Click += new EventHandler(DriveBox_Click);
            DriveBox.MouseEnter += new EventHandler(DriveBox_MouseEnter);
            DriveBox.MouseLeave += new EventHandler(DriveBox_MouseLeave);

            DriveInfo.AutoSize = true;
            DriveInfo.Dock = DockStyle.Fill;
            DriveInfo.Location = new Point(52, 39);
            DriveInfo.Name = "SpaceIndicator";
            DriveInfo.Size = new Size(35, 13);
            DriveInfo.Text = ConsoleUI.DFileSize(di.TotalSize) + " / " + ConsoleUI.DFileSize(di.TotalFreeSpace) + " Free";
 
            DriveUsage.Dock = DockStyle.Top;
            DriveUsage.Location = new Point(52, 16);
            DriveUsage.Name = "DriveUsage";
            DriveUsage.Size = new Size(229, 23);
            float percent = (((float)di.TotalSize - di.TotalFreeSpace) / di.TotalSize) * 100;
            DriveUsage.BackColor = Color.Red;

            DriveIcon.Dock = DockStyle.Left;
            DriveIcon.Location = new Point(3, 16);
            DriveIcon.Name = "DriveIcon";
            DriveIcon.Size = new Size(49, 40);
            DriveIcon.SizeMode = PictureBoxSizeMode.CenterImage;
            DriveIcon.TabStop = false;
            DriveIcon.Image = this.GetDriveIcon(di.DriveType);
            this.DrivePanel.Controls.Add(DriveBox);
        }

        void DriveBox_MouseLeave(object sender, EventArgs e)
        {
            GroupBox s = (GroupBox)sender;
            s.BackColor = DrivePanel.BackColor;
        }

        void DriveBox_MouseEnter(object sender, EventArgs e)
        {
            GroupBox s = (GroupBox)sender;
            s.BackColor = Color.Azure;
        }

        void DriveBox_Click(object sender, EventArgs e)
        {
            GroupBox s = (GroupBox)sender;
            this.DrivePanel.Visible = false;
            this.LoadFolder(s.Name);
        }

        private Image GetDriveIcon(DriveType t)
        {
            switch (t)
            {
                case DriveType.Fixed:
                    return this.Devices.Images[1];
                case DriveType.CDRom:
                    return this.Devices.Images[2];
                case DriveType.Network:
                    return this.Devices.Images[3];
                case DriveType.Removable:
                    return this.Devices.Images[4];
                default:
                    return this.Devices.Images[0];
            }

        }

        private int GetFileIcon(string fext)
        {
            if (Directory.Exists(fext)) return 1;
            else
            {
                string extension = Path.GetExtension(fext).ToUpper();
                switch (extension)
                {
                    case ".DOC":
                    case ".DOCX":
                    case ".ODT":
                        return 2;
                    case ".TXT":
                    case ".NFO":
                        return 3;
                    case ".EXE":
                    case ".COM":
                        return 4;
                    case ".WAV":
                    case ".MP3":
                    case ".OGG":
                    case ".WMA":
                    case ".FLAC":
                    case ".WV":
                        return 5;
                    case ".BMP":
                    case ".JPG":
                    case ".GIF":
                    case ".TIF":
                    case ".WMF":
                    case ".EMF":
                    case ".CRAW":
                    case ".TGA":
                        return 6;
                    case ".HTML":
                    case ".ASP":
                    case ".PHP":
                    case ".JSP":
                    case ".XHTML":
                    case ".MHT":
                        return 7;
                    case ".DLL":
                    case ".DRV":
                    case ".SYS":
                    case ".VXD":
                    case ".CPL":
                        return 8;
                    default:
                        return 0;
                }
            }
        }

        private void CreateDriveList()
        {
            ToolStripMenuItem drvbtn;
            DriveInfo di;
            string[] drives = Directory.GetLogicalDrives();
            Array.Sort(drives);
            foreach (string drive in drives)
            {
                try
                {
                    di = new DriveInfo(drive);
                    drvbtn = new ToolStripMenuItem();
                    drvbtn.Image = this.GetDriveIcon(di.DriveType);
                    InsertDriveToList(di);
                    drvbtn.Text = drive + " " + di.VolumeLabel;
                    drvbtn.Click += new EventHandler(drvbtn_Click);
                    drvbtn.ToolTipText = drive + " - " + di.VolumeLabel;
                    DrvList.DropDownItems.Add(drvbtn);
                }
                catch (Exception) { }
            }
            di = null;
        }

        private void drvbtn_Click(object sender, EventArgs e)
        {
            ToolStripMenuItem s = (ToolStripMenuItem)sender;
            this.DrivePanel.Visible = false;
            this.LoadFolder(s.Text[0] + ":\\");
        }

        #region Tree View

        private void fsTree_AfterCollapse(object sender, TreeViewEventArgs e)
        {
            e.Node.Nodes.Clear();
            e.Node.Nodes.Add("."); // need a node in there to spark the expand.
        }

        private void fsTree_BeforeExpand(object sender, TreeViewCancelEventArgs e)
        {
            try
            {
                e.Node.Nodes.Clear();
                string needle = (string)e.Node.Tag;
                string[] folders = Directory.GetDirectories(needle);
                string[] files = Directory.GetFiles(needle);

                foreach (string folder in folders)
                {
                    try
                    {
                        string[] s_folders = Directory.GetDirectories(folder);
                        string[] s_files = Directory.GetFiles(folder);

                        TreeNode t_folder = getNode(folder);
                        foreach (string s_folder in s_folders)
                        {
                            t_folder.Nodes.Add(getNode(s_folder));
                        }
                        foreach (string s_file in s_files)
                        {
                            t_folder.Nodes.Add(getNode(s_file));
                        }
                        e.Node.Nodes.Add(t_folder);
                    }
                    catch (IOException) { }
                    catch (UnauthorizedAccessException) { }
                    finally { }
                }

                foreach (string file in files)
                {
                    e.Node.Nodes.Add(getNode(file));
                }
            }
            catch (IOException) { }
            catch (UnauthorizedAccessException) { }
            finally { }
        }

        public void LoadFolder(string needle)
        {
            this.fsTree.Nodes.Clear();
            TreeNode nNode = getNode(needle);
            nNode.Nodes.Add("."); // need a node in there to spark the expand.
            this.fsTree.Nodes.Add(nNode);
            this.fsTree.Nodes[0].Expand();
        }

        private TreeNode getNode(string path)
        {
            TreeNode rNode = new TreeNode();
            int limit = path.LastIndexOf('\\') + 1;
            string name = path.Substring(limit, (path.Length - limit));
            if (name.Length < 1) name = path.Substring(0, (path.Length - 1));
            rNode.Text = name;
            rNode.ImageIndex = GetFileIcon(path);
            rNode.Tag = path;
            rNode.SelectedImageIndex = rNode.ImageIndex;
            return rNode;
        }

        #endregion

        private void copyFilePathToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Clipboard.SetText(fsTree.SelectedNode.FullPath);
        }

        private void openToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Process p = new Process();
            p.StartInfo.UseShellExecute = true;
            p.StartInfo.FileName = fsTree.SelectedNode.FullPath;
            p.Start();
        }

        private void DrvList_ButtonClick(object sender, EventArgs e)
        {
            if (!this.DrivePanel.Visible) this.DrivePanel.Visible = true;
        }
    }
}
